
package com.shenghui.enterprise.utils;

import com.alibaba.fastjson.JSONArray;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description: 常用工具类
 * @Author houjh
 * @Email: happyxiaohou@gmail.com
 * @Date: 2020-05-29
 * @Copyright (c) 2020-2022 云南昇晖科技有限公司
 */
public class GeneralUtil {
	private GeneralUtil(){}
	
	/**
	 * <p>检测给定的对象是否不为<code>null</code> 并且是一个 <code>{@link Integer}</code>
	 * 或是一个能被转换为 <code>{@link Integer}</code> 对象.</p>
	 * @param checkObj 需要被检测的对象
	 * @return 被检测的对象是一个 <code>{@link Integer}</code>
	 * 对象并且不为空则或是一个可以被转换为 {@link Integer}
	 * 类型的字符串时返回 <code>true</code>, 否则返回 <code>false</code> .
	 * */
	public static boolean isInteger(Object checkObj) {
		if (checkObj == null) {
			return false;
		}

		if (String.class.isAssignableFrom(checkObj.getClass())) {
			try {
				Integer.parseInt(checkObj.toString());
				return true;
			} catch (Exception ex) {
				return false;
			}
		}

		if (Integer.class.isAssignableFrom(checkObj.getClass())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * <p>检测给定的对象是否不为 <code>null</code> 并且是一个 <code>{@link Long}</code>
	 * 或是一个能被转换为 <code>{@link Long}</code> 对象.</p>
	 * @param checkObj 需要被检测的对象
	 * @return 被检测的对象是一个 <code>{@link Long}</code>
	 * 对象并且不为空则或是一个可以被转换为 {@link Long}
	 * 类型的字符串时返回 <code>true</code>, 否则返回 <code>false</code> .
	 * */
	public static boolean isLong(Object checkObj) {
		if (checkObj == null) {
			return false;
		}

		if (String.class.isAssignableFrom(checkObj.getClass())) {
			try {
				Long.parseLong(checkObj.toString());
				return true;
			} catch (Exception ex) {
				return false;
			}
		}

		if (Long.class.isAssignableFrom(checkObj.getClass())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * <p>检测给定的对象是否不为 <code>null</code> 并且是一个 <code>{@link Float}</code>
	 * 或是一个能被转换为 <code>{@link Float}</code> 对象.</p>
	 * @param checkObj 需要被检测的对象
	 * @return 被检测的对象是一个 <code>{@link Float}</code>
	 * 对象并且不为空则或是一个可以被转换为 {@link Float}
	 * 类型的字符串时返回 <code>true</code>, 否则返回 <code>false</code> .
	 * */
	public static boolean isFloat(Object checkObj) {
		if (checkObj == null) {
			return false;
		}

		if (String.class.isAssignableFrom(checkObj.getClass())) {
			try {
				Float.parseFloat(checkObj.toString());
				return true;
			} catch (Exception ex) {
				return false;
			}
		}

		if (Float.class.isAssignableFrom(checkObj.getClass())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * <p>检测给定的对象是否不为 <code>null</code> 并且是一个 <code>{@link Double}</code>
	 * 或是一个能被转换为 <code>{@link Double}</code> 对象.</p>
	 * @param checkObj 需要被检测的对象
	 * @return 被检测的对象是一个 <code>{@link Double}</code>
	 * 对象并且不为空则或是一个可以被转换为 {@link Double}
	 * 类型的字符串时返回 <code>true</code>, 否则返回 <code>false</code> .
	 * */
	public static boolean isDouble(Object checkObj) {
		if (checkObj == null) {
			return false;
		}

		if (String.class.isAssignableFrom(checkObj.getClass())) {
			try {
				Double.parseDouble(checkObj.toString());
				return true;
			} catch (Exception ex) {
				return false;
			}
		}
		if (Double.class.isAssignableFrom(checkObj.getClass())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * <p>检则一个对象是否不为空, 如果为字符串则会剔除空格来进行验证.</p>
	 * <p style="color:red;">字符串数据 <code>""</code> 同样为视为 <code>null</code> .</p>
	 * @param checkObj 需要被检测的对象
	 * @return 如查不为空,返回<code>true</code>,如果为空返回<code>false</code>.
	 * */
	public static boolean isNotNull(Object checkObj){
		if(checkObj == null || "null".equals(checkObj)) {
			return false;
		}

		if (String.class.isAssignableFrom(checkObj.getClass())) {
			if("".equals(checkObj.toString().trim())) {
				return false;
			}
		}

		return true;
	}

	/**
	 * <p>检则一个对象是否不为空, 如果为字符串则会剔除空格来进行验证.</p>
	 * <p style="color:red;">字符串数据 <code>""</code> 同样为视为 <code>null</code> .</p>
	 * @param list 需要被检测的对象
	 * @return 如查不为空,返回<code>true</code>,如果为空返回<code>false</code>.
	 * */
	public static boolean isNotNullList(List<Object> list){
		if (isNotNull(list) && list.size() > 0) {
			return true;
		}
		return false;
	}


	/**
	 * <p>检测一个对象是否为空, 如果为字符串则会剔除空格进行验证.</p>
	 * <p style="color:red;">字符串数据 <code>""</code> 同样被视为 <code>null</code> .</p>
	 * @param checkObj 需要被检测的对象.
	 * @return 如果对象为空返回 <code>true</code> 不为空返回 <code>false</code> .
	 * */
	public static boolean isNull(Object checkObj) {
		if (checkObj == null) {
			return true;
		}

		if (String.class.isAssignableFrom(checkObj.getClass())) {
			if (checkObj.toString().trim().length() < 1 ||
					"".equals(checkObj.toString().trim())||
					"null".equals(checkObj.toString().trim())||
			checkObj.toString().trim() == null)
				return true;
		}

		return false;
	}

	/**
	 * 检查字符串是否在minLength和maxLength之间,
	 * 如查strValue为<code>null</code>或minLength大于maxLength都
	 * 将直接返回<code>false</code>.此方法不会剔除字符串中的空格
	 * 来进行检查,如果字符串长度是在minLength和
	 * maxLength之间将返回<code>true</code>
	 * @param strValue 需要检查的字符串
	 * @param minLength 字符串最小长度
	 * @param maxLength 字符串最大长度
	 * @return 在minLength之间返回<code>true</code>,否则返回<code>false</code>.
	 * */
	public static boolean checkLength(String strValue, Integer minLength, Integer maxLength){
		if(strValue == null) {
			return false;
		}

		if(minLength > maxLength) {
			return false;
		}

		if(strValue.length() >= minLength && strValue.length() <= maxLength) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 取得一个按指定编码转换的字符
	 * @param sourceString 需要转换的源字符串
	 * @param changeEncoding 改变后的字符串编码
	 * @return 成功则返回转换成功的字符串,失败则返回<code>null</code>对象
	 * */
	public static String getStringFromEncoding(String sourceString, String changeEncoding) {
		try {
			return new String(sourceString.getBytes(), changeEncoding);
		} catch (UnsupportedEncodingException e) {
			return null;
		}
	}

	/**
	 * 取得一个按指定编号转换的字符
	 * @param sourceString 需要转换的源字符串
	 * @param getSourceEncoding 取得源字符串的编号
	 * @param changeEncoding 改变后的字符串编码
	 * @return 成功则返回转换成功的字符串,失败则返回<code>null</code>对象
	 * */
	public static String getStringFromEncoding(
			String sourceString, String getSourceEncoding, String changeEncoding) {
		try {
			sourceString = new String(sourceString.getBytes(getSourceEncoding), changeEncoding);
			return sourceString;
	    } catch(UnsupportedEncodingException e){
	    	return null;
	    }
	}

	/**
	 * 获得文件存储的随机时间
	 */
	public String getRandomTime() {
		SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddhhmmss");
        String strCreateDate = fmt.format(new Date().getTime()); //文件创建日期
        return strCreateDate;
	}

	/**
	 * 获得文件存储的随机时间
	 */
	public static String getRandom(Integer len) {
		if (GeneralUtil.isNull(len)) len = 5;
	    Random random = new Random();
	    String result = "";
	    for (int i = 0; i < len; i++) {
	        result += random.nextInt(10);
	    }
	    return result;
	}

	/**
	 *
	 * removeHTMLTag(移除指定字符串的HTML标记)
	 * @param content 指定的字符串
	 * @return {@link String} 返回移除HTML标记后的字符串
	 */
	public static String removeHtmlTags(String content) {
		String temp = content.replaceAll("\\s*|\t|\r|\n|nbsp;", "").replaceAll(
				"<.*?>", "").replaceAll("&.*?;", "").replaceAll(
				"^[0-9a-zA-Z\u00ff\uffff]", "");
		return temp;
	}
	
	/**
	 * 
	 * getAbsoultePath(获取服务器的绝对路径)
	 * @return 当前项目所在的绝对路径
	 */
	public static String getAbsoultePath() {
		return GeneralUtil.class.getResource("/").getPath();
	}
	
	/**
	 * 
	 * subString(按照指定的字符串和长度,返回截取长度后的字符串)
	 * @param value 要截取的字符串
	 * @param size  要截取的大小
	 * @return 返回截取后的字符串
	 */
	public static String subString(String value, int size) {
		if(!GeneralUtil.isNull(value)) {
			if (value.length() < size) {
				return value;
			} else {
				return value.substring(0, size);
			}
		} else {
			return null;
		}
	}
	
	/**
	 * 
	 * getSizeBySeparator(根据分割符来返回字符串中分割字符串后的个数)
	 * @param strSource 要分割的字符串
	 * @param separator 分隔符号
	 * @return 分割后的个数
	 */
	public static int getSizeBySeparator(String strSource, String separator) {
		int intPos = 0;
		int i = 1;
		while ((intPos = strSource.indexOf(separator)) != -1) {
			String temp = strSource.substring(intPos + 1, strSource.length());
			strSource = temp;
			i++;
		}
		return i;
	}
	
	/**
	 * 全部替换字符串方法
	 * @param strSource 源字符串
	 * @param strFrom   原字符串
	 * @param strTo     目标字符串
	 * @return 替换后的字符串
	 */
	public String replace(String strSource, String strFrom, String strTo) {
		if (strFrom == null || strFrom.equals("")) {
			return strSource;
		}
		int intFromLen = strFrom.length();
		int intPos;
		String strDest = "";
		while ((intPos = strSource.indexOf(strFrom)) != -1) {
			strDest = strDest + strSource.substring(0, intPos);
			strDest = strDest + strTo;
			strSource = strSource.substring(intPos + intFromLen);
		}
		strDest = strDest + strSource;
		return strDest;
	}

	/**
	 * 部分替换字符串，指定开始替换位置和指定替换次数的函数
	 * @param strSource    源字符串
	 * @param strFrom      原字符串
	 * @param strTo        目标字符串
	 * @param intStart     开始位置
	 * @param intCount     替换次数
	 * @return             替换后的字符串
	 */
	public String replace(String strSource, String strFrom, String strTo,
			int intStart, int intCount) {
		if (intCount < 0) {
			intCount = strSource.length();
		}
		if (strSource == null) {
			return strSource;
		}
		int intFromLen = strFrom.length();
		int runCount = 1;
		int intPos;
		String strDest = "";
		while (((intPos = strSource.indexOf(strFrom, intStart)) != -1)
				&& (runCount <= intCount)) {
			runCount += 1;
			strDest = strDest + strSource.substring(0, intPos);
			strDest = strDest + strTo;
			strSource = strSource.substring(intPos + intFromLen);
		}
		strDest = strDest + strSource;
		return strDest;
	}
	
	
	/**
	 * getStringByLen   (获取字符串的长度)
	 * @param sourceStr 源字符串
	 * @param strLen    获取的长度
	 * @param hasOmit   是否忽略 
	 * 	<p>当源字符串的长度大于strLen时, 如果hasOmit为true, 
	 * 	则用...填充, 如果为false则不进行填充</p> 
	 */
	public static String getStringByLen(String sourceStr, int strLen, boolean hasOmit) {
		strLen = strLen * 2;
		int newLen = 0; // 计算字符串长度
		int charLen = 0;
		String omitStr = hasOmit ? "..." : "";

		for (int i = 0; i < sourceStr.length(); i++) {
			if (sourceStr.charAt(i) > 255) {
				charLen = 2;
			} else {
				charLen = 1;
			}
			// 获得当前字符串长度
			newLen = newLen + charLen;
			if (newLen >= strLen) {
				// 获得希望的字符位置
				return (sourceStr.substring(0, i) + omitStr).replaceAll(" ",
						"&nbsp;");

			}
		}
		return sourceStr.replaceAll(" ", "&nbsp;");
	}
	
	/**
	 * 内部UBB代码，目前支持[b],[i],[br],[url],[color],[size]
	 * 
	 * @param ubbstr     源字符串
	 * @param showimg    显示图像？
	 * @param showplayer 显示媒体？
	 * @return
	 */
	public String UBB2HTML(String ubbstr, boolean showimg, boolean showplayer) {
		if (!ubbstr.equals("")) {
			String str = replace(ubbstr, "[b]", "<b>");
			str = replace(str, "[/b]", "</b>");
			str = replace(str, "[i]", "<i>");
			str = replace(str, "[/i]", "</i>");
			str = replace(str, "[br]", "<br>");

			String tempStr = "";
			tempStr = UBBStr(str, "url");
			tempStr = UBBStr(tempStr, "color");
			tempStr = UBBStr(tempStr, "size");
			return tempStr;
		} else {
			return ubbstr;
		}
	}

	public String UBB2HTML(String ubbstr) {
		return UBB2HTML(ubbstr, true, true);
	}

	/**
	 * 内部UBB内部方法
	 * @param str   源字符串
	 * @param key   ubb关键字
	 * @return   ubb2html字符串
	 */
	public String UBBStr(String str, String key) {
		String tempStr = str;
		if (tempStr == null) {
			return tempStr;
		}
		tempStr = replace(tempStr, "[/url]", "</a>");
		tempStr = replace(tempStr, "[/color]", "</font>");
		tempStr = replace(tempStr, "[/size]", "</font>");
		String text = "";
		int begin = 0;
		int end = 0;
		while ((begin = tempStr.indexOf("[" + key + "=", begin)) >= 0) {
			begin = begin + key.length() + 2;
			end = tempStr.indexOf("]", begin);
			text = tempStr.substring(begin, end);
			if (key.equals("url")) {
				tempStr = replace(tempStr, "[url=" + text + "]",
						"<a target=_blank href=\"" + text + "\">", 0, 1);
			}
			if (key.equals("color")) {
				tempStr = replace(tempStr, "[color=" + text + "]",
						"<font color=\"" + text + "\">", 0, 1);
			}
			if (key.equals("size")) {
				tempStr = replace(tempStr, "[size=" + text + "]",
						"<font size=\"" + text + "\">", 0, 1);
			}
		}
		return tempStr;
	}
	
	//转换map中的数组为逗号分割的字符串,转移非法字符
	public static Map<String, String> parseArrayInMapToString(Map<String, String> map) {
		if (!GeneralUtil.isNull(map)) {
			Iterator<String> iterator = map.keySet().iterator();
			while (iterator.hasNext()) {
				String key = iterator.next();
				Object value = map.get(key);
				if (value instanceof JSONArray) {
					JSONArray jsonArray = (JSONArray) value;
					StringBuilder sb = new StringBuilder();
					for (Object j : jsonArray) {
						sb.append(",").append(j);
					}
					if (sb.length() > 1) {
						value = sb.substring(1);
					} else {
						value = "";
					}
				}
				value = parseSqlValue(value);
				map.put(key, String.valueOf(value));
			}
			return map;
		}
		return null;
	}
	
	//转化sql中的非法字符
	public static Object parseSqlValue(Object value) {
		if (value instanceof String) {
			value = ((String)value).replace("\'", "\\'");
			return value;
		}
		return value;
	}
	
}
